package com.kanshu.client.ui.activity.ipc;

import android.app.Service;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.IBinder;
import android.os.RemoteException;

import com.kanshu.basictest.IBinderPool;

import java.lang.ref.WeakReference;
import java.util.concurrent.CountDownLatch;

public final class BinderPoolHelper {

    private static final String TAG = "BinderPoolHelper";

    private WeakReference<Context> mContextWR;
    private IBinderPool mBinderPool;
    //单例
    private static volatile BinderPoolHelper sInstance;

    private CountDownLatch mConnectBinderPoolCountDownLatch;


    private BinderPoolHelper(Context context) {
        mContextWR = new WeakReference<>(context);
        connectBinderPoolService();
    }


    public static BinderPoolHelper getInstance(Context context) {
        if (sInstance == null) {
            synchronized (BinderPoolHelper.class) {
                if (sInstance == null) {
                    sInstance = new BinderPoolHelper(context);
                }
            }
        }
        return sInstance;
    }


    private synchronized void connectBinderPoolService() {
        mConnectBinderPoolCountDownLatch = new CountDownLatch(1);
        Intent service = new Intent();
        service.setComponent(new ComponentName("com.kanshu.basictest", "com.kanshu.basictest.service.BinderPoolService"));
        mContextWR.get().bindService(service, mBinderPoolServiceConn, Service.BIND_AUTO_CREATE);
        try {
            mConnectBinderPoolCountDownLatch.await();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }


    }

    public IBinder queryBinder(int binderCode) {

        IBinder binder = null;
        try {
            if (mBinderPool != null) {
                binder = mBinderPool.queryBinder(binderCode);
            }
        } catch (RemoteException e) {
            e.printStackTrace();
        }

        return binder;
    }


    private ServiceConnection mBinderPoolServiceConn = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            mBinderPool = IBinderPool.Stub.asInterface(service);
            try {
                mBinderPool.asBinder().linkToDeath(mDeathRecipient, 0);
            } catch (RemoteException e) {
                e.printStackTrace();
            }
            mConnectBinderPoolCountDownLatch.countDown();
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {

        }
    };


    private IBinder.DeathRecipient mDeathRecipient = new IBinder.DeathRecipient() {
        @Override
        public void binderDied() {
            if (mBinderPool == null) return;

            mBinderPool.asBinder().unlinkToDeath(mDeathRecipient, 0);
            mBinderPool = null;
            connectBinderPoolService();
        }
    };
}
